import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

enum DirectionMovement {
  center,
  right,
  up,
  left,
  down,
  topRight, //斜角方向
  topLeft,
  bottomLeft,
  bottomRight
}

class JoystickWidget extends StatefulWidget {
  final double zoneR; //外层大小
  final double handleR; //摇杆大小
  final Function(DirectionMovement)? onHandleListener; //触发方向
  final Color backgroundColor; //外层颜色
  final Color borderColor; //边框颜色
  final Color buttonColor; //方向颜色
  final Color centerColor; //摇杆颜色
  final bool isActivate; // 是否可以移动摇杆
  final bool isSupportVertical; //是否支持上下
  final bool isSupportHorizontal; //是否支持左右
  final bool isSupport; //是否支持8个方向
  JoystickWidget({
    this.zoneR = 40.0,
    this.handleR = 15.0,
    this.onHandleListener,
    this.backgroundColor = Colors.black54,
    this.borderColor = Colors.white,
    this.buttonColor = Colors.white,
    this.centerColor = Colors.white,
    this.isActivate = true,
    this.isSupportVertical = true,
    this.isSupportHorizontal = true,
    this.isSupport = false,
  });

  @override
  _JoystickWidgetState createState() => _JoystickWidgetState();
}

class _JoystickWidgetState extends State<JoystickWidget> {
  late double zoneR;
  late double handleR;
  double centerX = 0.0;
  double centerY = 0.0;
  DirectionMovement _direction = DirectionMovement.center;


  @override
  void initState() {
    zoneR = widget.zoneR;
    handleR = widget.handleR;
    super.initState();
  }

  // 手指抬起触发
  reset() {
    centerX = 0;
    centerY = 0;
    _direction = DirectionMovement.center;

    if (widget.onHandleListener != null) {
      widget.onHandleListener!(_direction);
    }
    setState(() {});
  }

  // 移动时触发
  parser(Offset offset) {
    centerX = offset.dx - maxR;
    centerY = offset.dy - maxR;

    double rad = atan2(centerY, centerX); // 注意这里反转
    if (rad < 0) rad += 2 * pi; // 保证范围 0~2π

    // 限制摇杆范围
    if (sqrt(centerX * centerX + centerY * centerY) > zoneR) {
      centerX = zoneR * cos(rad);
      centerY = zoneR * sin(rad);
    }



    // 八方向角度范围
    // 每 45° 一个方向，偏移 22.5° 做中间分割
    if (rad >= 337.5 * pi / 180 || rad < 22.5 * pi / 180) {
      _direction = DirectionMovement.right;

    }
    else if (rad >= 22.5 * pi / 180 && rad < 67.5 * pi / 180) {
      _direction = widget.isSupport? DirectionMovement.bottomRight:DirectionMovement.down;

    }
    else if (rad >= 67.5 * pi / 180 && rad < 112.5 * pi / 180) {
      _direction = DirectionMovement.down;

    }
    else if (rad >= 112.5 * pi / 180 && rad < 157.5 * pi / 180) {
      _direction = widget.isSupport? DirectionMovement.bottomLeft:DirectionMovement.down;

    }
    else if (rad >= 157.5 * pi / 180 && rad < 202.5 * pi / 180) {
      _direction = DirectionMovement.left;

    }
    else if (rad >= 202.5 * pi / 180 && rad < 247.5 * pi / 180) {

      _direction = widget.isSupport? DirectionMovement.topLeft:DirectionMovement.up;

    }
    else if (rad >= 247.5 * pi / 180 && rad < 292.5 * pi / 180) {
      _direction = DirectionMovement.up;

    }
    else if (rad >= 292.5 * pi / 180 && rad < 337.5 * pi / 180) {
      _direction = widget.isSupport? DirectionMovement.topRight:DirectionMovement.up;

    }

    // 回调
    if (widget.onHandleListener != null) {
      widget.onHandleListener!(_direction);
    }

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onHorizontalDragStart: (a) => {},
      onHorizontalDragUpdate: (a) => {},
      onHorizontalDragEnd: (a) => {},
      onVerticalDragStart: (a) => {},
      onVerticalDragUpdate: (a) => {},
      onVerticalDragEnd: (a) => {},
      child: Listener(
        onPointerUp: (d) => widget.isActivate ? reset() : {},
        onPointerMove: (d) => widget.isActivate ? parser(d.localPosition) : {},
        onPointerDown: (d) => widget.isActivate ? parser(d.localPosition) : {},
        child: Container(
          width: maxR * 2,
          height: maxR * 2,
          clipBehavior: Clip.hardEdge,
          decoration: BoxDecoration(
            color: widget.backgroundColor,
            border: Border.all(color: widget.borderColor, width: .0),
            borderRadius: BorderRadius.circular(maxR),
          ),
          child: Stack(
            children: [
              CustomPaint(
                painter: _HandleView(
                  zoneR: zoneR,
                  handleR: handleR,
                  centerX: centerX,
                  centerY: centerY,
                  centerColor: widget.centerColor,
                ),
              ),
// 上 渐变
              Align(
                alignment: Alignment.topCenter,
                child: Visibility(
                  visible: (_direction == DirectionMovement.up &&
                      widget.isSupportVertical),
                  child: Container(
                    width: maxR * 2,
                    height: maxR / 2,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.topCenter,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),
// 下
              Align(
                alignment: Alignment.bottomCenter,
                child: Visibility(
                  visible: (_direction == DirectionMovement.down &&
                      widget.isSupportVertical),
                  child: Container(
                    width: maxR * 2,
                    height: zoneR / 2,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.bottomCenter,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

// 左
              Align(
                alignment: Alignment.centerLeft,
                child: Visibility(
                  visible: (_direction == DirectionMovement.left &&
                      widget.isSupportHorizontal),
                  child: Container(
                    width: zoneR / 2,
                    height: maxR * 2,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.centerLeft,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

// 右
              Align(
                alignment: Alignment.centerRight,
                child: Visibility(
                  visible: (_direction == DirectionMovement.right &&
                      widget.isSupportHorizontal),
                  child: Container(
                    width: zoneR / 2,
                    height: maxR * 2,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.centerRight,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

// 左上
              Align(
                alignment: Alignment.topLeft,
                child: Visibility(
                  visible: (_direction == DirectionMovement.topLeft &&
                      widget.isSupport),
                  child: Container(
                    width: maxR,
                    height: maxR,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.topLeft,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

// 右上
              Align(
                alignment: Alignment.topRight,
                child: Visibility(
                  visible: (_direction == DirectionMovement.topRight &&
                      widget.isSupport),
                  child: Container(
                    width: maxR,
                    height: maxR,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.topRight,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

// 左下
              Align(
                alignment: Alignment.bottomLeft,
                child: Visibility(
                  visible: (_direction == DirectionMovement.bottomLeft &&
                      widget.isSupport),
                  child: Container(
                    width: maxR,
                    height: maxR,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.bottomLeft,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

// 右下
              Align(
                alignment: Alignment.bottomRight,
                child: Visibility(
                  visible: (_direction == DirectionMovement.bottomRight &&
                      widget.isSupport),
                  child: Container(
                    width: maxR,
                    height: maxR,
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.center,
                        end: Alignment.bottomRight,
                        colors: [
                          Color.fromRGBO(70, 188, 213, 0),
                          Color.fromRGBO(70, 188, 213, 1),
                        ],
                      ),
                    ),
                  ),
                ),
              ),

// 上   箭头
              Arrows(
                  isSupportHorizontal: widget.isSupportHorizontal,
                  isSupportVertical: widget.isSupportVertical,
                  isSupport: widget.isSupportVertical,
                  imagePage: 'assets/dog_play_direction_up.png',
                  ImageColor: 0xFFDBDCDD),
// 斜角 箭头
              Visibility(
                  child: Transform.rotate(
                      angle: 45 * pi/ 180,
                      child: Arrows(
                          isSupportHorizontal: widget.isSupportHorizontal,
                          isSupportVertical: widget.isSupportVertical,
                          isSupport: widget.isSupportVertical,
                          imagePage: 'assets/dog_play_direction_up.png',
                          ImageColor: 0xFFDBDCDD)),
                  visible: widget.isSupport)
            ],
          ),
        ),
      ),
    );
  }

  double get maxR => zoneR + handleR;
}

class Arrows extends StatelessWidget {
  const Arrows(
      {super.key,
      required this.isSupportVertical,
      required this.isSupportHorizontal,
      required this.isSupport,
      required this.imagePage,
      required this.ImageColor});

  final bool isSupportVertical; //是否支持上下
  final bool isSupportHorizontal; //是否支持左右
  final bool isSupport; //是否支持8个方向
  final String imagePage;
  final int ImageColor;

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Stack(children: [
      // 上 箭头
      Align(
        alignment: Alignment.topCenter,
        child: Visibility(
          child: Container(
            margin: EdgeInsets.only(top: 5),
            child: RotatedBox(
              child: ImageIcon(
                AssetImage(imagePage),
                size: 15,
                color: Color(ImageColor),
              ),
              quarterTurns: 0,
            ),
          ),
          visible: isSupportVertical,
        ),
      ),
      // 右
      Align(
        alignment: Alignment.centerRight,
        child: Visibility(
          child: Container(
            margin: EdgeInsets.only(right: 5),
            child: RotatedBox(
              child: ImageIcon(
                AssetImage(imagePage),
                size: 15,
                color: Color(ImageColor),
              ),
              quarterTurns: 1,
            ),
          ),
          visible: isSupportHorizontal,
        ),
      ),
      // 下
      Align(
        alignment: Alignment.bottomCenter,
        child: Visibility(
          child: Container(
            margin: EdgeInsets.only(bottom: 5),
            child: RotatedBox(
              child: ImageIcon(
                AssetImage(imagePage),
                size: 15,
                color: Color(ImageColor),
              ),
              quarterTurns: 2,
            ),
          ),
          visible: isSupportVertical,
        ),
      ),
      // 左
      Align(
        alignment: Alignment.centerLeft,
        child: Visibility(

          child:  Container(
            margin: EdgeInsets.only(left: 5),
            child: RotatedBox(
              child: ImageIcon(
                AssetImage(imagePage),
                size: 15,
                color: Color(ImageColor),
              ),
              quarterTurns: 3,
            ),
          ),
          visible: isSupportHorizontal,
        ),
      ),
    ]));
  }
}

///画板
class _HandleView extends CustomPainter {
  var _paint = Paint();
  var zoneR;
  var handleR;
  var centerX;
  var centerY;
  Color? centerColor;

  _HandleView(
      {this.zoneR,
      this.handleR,
      this.centerX,
      this.centerY,
      this.centerColor}) {
    _paint
      ..color = Colors.white
      ..style = PaintingStyle.fill
      ..isAntiAlias = true;
  }

  double get maxR => zoneR + handleR;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.translate(maxR, maxR);
    // 设置画笔颜色。
    _paint.color = centerColor!.withAlpha(250);
    canvas.drawCircle(Offset(centerX, centerY), handleR, _paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
